"""
通用辅助工具
"""

import json
import uuid
import hashlib
from datetime import datetime, timezone
from typing import Any, Dict, Optional, Union
from app.core.logging import get_logger

logger = get_logger(__name__)


def generate_unique_id(prefix: str = "", length: int = 8) -> str:
    """
    生成唯一ID

    Args:
        prefix: ID前缀
        length: ID长度（不包括前缀）

    Returns:
        唯一ID字符串
    """
    unique_part = str(uuid.uuid4()).replace('-', '')[:length]
    return f"{prefix}{unique_part}" if prefix else unique_part


def generate_test_case_id(sequence: int) -> str:
    """
    生成测试用例ID

    Args:
        sequence: 序列号

    Returns:
        格式化的测试用例ID (test_001, test_002, ...)
    """
    return f"test_{sequence:03d}"


def format_datetime(dt: Optional[datetime] = None, format_str: str = "%Y-%m-%d %H:%M:%S") -> str:
    """
    格式化日期时间

    Args:
        dt: 日期时间对象，默认为当前时间
        format_str: 格式字符串

    Returns:
        格式化后的日期时间字符串
    """
    if dt is None:
        dt = datetime.now(timezone.utc)

    return dt.strftime(format_str)


def safe_json_loads(json_str: str, default: Any = None) -> Any:
    """
    安全的JSON解析

    Args:
        json_str: JSON字符串
        default: 解析失败时的默认值

    Returns:
        解析后的对象或默认值
    """
    if not json_str:
        return default

    try:
        return json.loads(json_str)
    except (json.JSONDecodeError, TypeError) as e:
        logger.warning(f"JSON解析失败: {e}, 原始字符串: {json_str[:100]}...")
        return default


def safe_json_dumps(obj: Any, default: str = "{}") -> str:
    """
    安全的JSON序列化

    Args:
        obj: 要序列化的对象
        default: 序列化失败时的默认值

    Returns:
        JSON字符串或默认值
    """
    try:
        return json.dumps(obj, ensure_ascii=False, indent=2)
    except (TypeError, ValueError) as e:
        logger.warning(f"JSON序列化失败: {e}, 对象类型: {type(obj)}")
        return default


def calculate_md5(text: str) -> str:
    """
    计算文本的MD5哈希值

    Args:
        text: 输入文本

    Returns:
        MD5哈希值
    """
    return hashlib.md5(text.encode('utf-8')).hexdigest()


def truncate_text(text: str, max_length: int = 100, suffix: str = "...") -> str:
    """
    截断文本

    Args:
        text: 输入文本
        max_length: 最大长度
        suffix: 截断后的后缀

    Returns:
        截断后的文本
    """
    if not text or len(text) <= max_length:
        return text

    return text[:max_length - len(suffix)] + suffix


def clean_text(text: str) -> str:
    """
    清理文本（移除多余空白字符）

    Args:
        text: 输入文本

    Returns:
        清理后的文本
    """
    if not text:
        return ""

    # 替换换行符为空格，移除多余空白
    cleaned = ' '.join(text.split())
    return cleaned.strip()


def normalize_priority(priority: str) -> str:
    """
    标准化优先级

    Args:
        priority: 优先级字符串

    Returns:
        标准化的优先级 (P1, P2, P3, P4)
    """
    if not priority:
        return "P2"  # 修改默认优先级为P2，更符合实际情况

    priority_upper = priority.upper().strip()

    # 处理各种可能的输入格式
    if priority_upper in ["P1", "HIGH", "高", "1"]:
        return "P1"
    elif priority_upper in ["P2", "MEDIUM", "中", "2"]:
        return "P2"
    elif priority_upper in ["P3", "NORMAL", "普通", "3"]:
        return "P3"
    elif priority_upper in ["P4", "LOW", "低", "4"]:
        return "P4"
    else:
        return "P2"  # 默认优先级改为P2


def assign_smart_priority(test_case_title: str, test_case_description: str = "") -> str:
    """
    基于测试用例标题和描述智能分配优先级

    Args:
        test_case_title: 测试用例标题
        test_case_description: 测试用例描述

    Returns:
        智能分配的优先级 (P1, P2, P3, P4)
    """
    title_lower = test_case_title.lower()
    desc_lower = test_case_description.lower()
    combined_text = f"{title_lower} {desc_lower}"

    # P1 关键词 - 核心功能、主流程
    p1_keywords = [
        "登录", "注册", "支付", "下单", "核心", "主流程", "关键", "重要",
        "基本功能", "主要功能", "核心业务", "必须", "关键路径"
    ]

    # P2 关键词 - 重要功能、常用场景
    p2_keywords = [
        "查询", "搜索", "列表", "详情", "编辑", "修改", "删除", "添加",
        "保存", "提交", "验证", "校验", "正常", "成功"
    ]

    # P3 关键词 - 辅助功能、边界条件
    p3_keywords = [
        "边界", "异常", "错误", "失败", "无效", "空值", "null", "特殊字符",
        "长度", "格式", "权限", "辅助", "可选", "非必须"
    ]

    # P4 关键词 - 非核心功能、极端场景
    p4_keywords = [
        "极端", "性能", "兼容", "浏览器", "设备", "网络", "超时",
        "并发", "压力", "稳定性", "可用性", "非功能"
    ]

    # 按优先级顺序检查关键词
    for keyword in p1_keywords:
        if keyword in combined_text:
            return "P1"

    for keyword in p2_keywords:
        if keyword in combined_text:
            return "P2"

    for keyword in p3_keywords:
        if keyword in combined_text:
            return "P3"

    for keyword in p4_keywords:
        if keyword in combined_text:
            return "P4"

    # 如果没有匹配到关键词，返回默认优先级P2
    return "P2"


def extract_keywords(text: str, min_length: int = 2) -> list:
    """
    从文本中提取关键词

    Args:
        text: 输入文本
        min_length: 关键词最小长度

    Returns:
        关键词列表
    """
    if not text:
        return []

    # 简单的关键词提取（基于常见分隔符）
    import re

    # 移除标点符号，分割文本
    words = re.findall(r'\b\w+\b', text.lower())

    # 过滤长度和常见停用词
    stop_words = {'的', '是', '在', '有', '和', '与', '或', '但', '如果', '那么', '这个', '那个',
                  'the', 'is', 'in', 'and', 'or', 'but', 'if', 'then', 'this', 'that'}

    keywords = [word for word in words
                if len(word) >= min_length and word not in stop_words]

    # 去重并保持顺序
    seen = set()
    unique_keywords = []
    for keyword in keywords:
        if keyword not in seen:
            seen.add(keyword)
            unique_keywords.append(keyword)

    return unique_keywords[:20]  # 最多返回20个关键词


def merge_dicts(*dicts: Dict[str, Any]) -> Dict[str, Any]:
    """
    合并多个字典

    Args:
        *dicts: 要合并的字典

    Returns:
        合并后的字典
    """
    result = {}
    for d in dicts:
        if isinstance(d, dict):
            result.update(d)
    return result


def is_valid_url(url: str) -> bool:
    """
    验证URL格式

    Args:
        url: URL字符串

    Returns:
        是否为有效URL
    """
    if not url:
        return False

    import re
    url_pattern = re.compile(
        r'^https?://'  # http:// or https://
        # domain...
        r'(?:(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+[A-Z]{2,6}\.?|'
        r'localhost|'  # localhost...
        r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})'  # ...or ip
        r'(?::\d+)?'  # optional port
        r'(?:/?|[/?]\S+)$', re.IGNORECASE)

    return url_pattern.match(url) is not None
